//检查路径
import cv from '@techstark/opencv-js';
//子线程代码


// imgObj: {
//     imgid: 1,
//     data: imageData.data,    // Uint8ClampedArray
//     width: originalMat.cols,
//     height: originalMat.rows,
//     channels: originalMat.channels()
//   },
//   threshold: 100
const processImage = (imgObj,threshold) => {
    const { data, width, height, channels1 } = imgObj;
    const resultsList=[]
    const invertedResultsList=[]
    const matsToDelete = []; // 用于跟踪需要释放的对象
    console.log(imgObj)
     // 重新构建 OpenCV Mat 对象
     const src = new cv.Mat(height, width, cv.CV_8UC4);
    src.data.set(data); // 将像素数据填充到 Mat
     let processingSrc = new cv.Mat();
     if(src.channels() === 4){
      cv.cvtColor(src,processingSrc,cv.COLOR_RGBA2BGR)
     }else{
      src.copyTo(processingSrc)
     }

     //克隆图转灰度
     let gray = new cv.Mat();
     cv.cvtColor(processingSrc,gray,cv.COLOR_BGR2GRAY)
     //生成掩膜
     const mask=new cv.Mat();
     cv.threshold(gray,mask,threshold,255,cv.THRESH_BINARY)
     //生成反掩膜
     const invertedMask=new cv.Mat();
     cv.bitwise_not(mask,invertedMask)
     //使用掩膜提取荧光强度
     const maskedImage=new cv.Mat();
     cv.bitwise_and(gray,gray,maskedImage,mask)
     //使用反掩膜提取荧光强度
     const invertedMaskedImage=new cv.Mat();
     cv.bitwise_and(gray,gray,invertedMaskedImage,invertedMask)
     //计算边界
     const contours=new cv.MatVector();
     const hierarchy=new cv.Mat();
     const invertedContours=new cv.MatVector();
     const invertedHierarchy=new cv.Mat();  
     cv.findContours(mask,contours,hierarchy,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
     cv.findContours(invertedMask,invertedContours,invertedHierarchy,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
     //绘制边界
     const contourMat = new cv.Mat.zeros(mask.rows, mask.cols, cv.CV_8UC3);
     const invertedContourMat = new cv.Mat.zeros(mask.rows, mask.cols, cv.CV_8UC3);
     cv.drawContours(contourMat,contours,-1,new cv.Scalar(255,0, 0,),2)
     cv.drawContours(invertedContourMat,invertedContours,-1,new cv.Scalar(255,0, 0,),2)
     //遍历每个轮廓

     for(let i=0;i<contours.size();i++){
      //创建一个掩膜，将轮廓内部的区域设置为 255，其他区域设置为 0
      const contourMask = new cv.Mat.zeros(mask.rows, mask.cols, cv.CV_8UC1);
      cv.drawContours(contourMask, contours, i, [255, 255, 255, 255], cv.FILLED);
      //计算轮廓内区域的均值
      const meanValue = cv.mean(maskedImage, contourMask)[0];
      // 计算轮廓内区域的最大值和最小值
      const minMaxLoc = cv.minMaxLoc(maskedImage, contourMask);
      const minValue = minMaxLoc.minVal;
      const maxValue = minMaxLoc.maxVal;
      resultsList.push({
        imgid:imgObj.imgid,id: i, mean:meanValue, max: maxValue, min:minValue
      })
      contourMask.delete(); // 立即释放
     }

     for(let i=0;i<invertedContours.size();i++){
      //创建一个掩膜，将轮廓内部的区域设置为 255，其他区域设置为 0
      const invertedContourMask = new cv.Mat.zeros(mask.rows, mask.cols, cv.CV_8UC1);
      cv.drawContours(invertedContourMask, invertedContours, i, [255, 255, 255, 255], cv.FILLED);
      //计算轮廓内区域的均值
      const invertedMeanValue = cv.mean(invertedMaskedImage, invertedContourMask)[0];
      // 计算轮廓内区域的最大值和最小值
      const invertedMinMaxLoc = cv.minMaxLoc(invertedMaskedImage, invertedContourMask);
      const invertedMinValue = invertedMinMaxLoc.minVal;
      const invertedMaxValue = invertedMinMaxLoc.maxVal;
      invertedResultsList.push({
        imgid:imgObj.imgid,id: i, mean:invertedMeanValue, max: invertedMaxValue, min:invertedMinValue
      })
      invertedContourMask.delete(); // 立即释放
     }
     //与原图叠加显示

     const combinedMat = new cv.Mat();
     const combinedInvertedMat = new cv.Mat();
     cv.addWeighted(processingSrc, 1, contourMat, 0.5, 0, combinedMat);
     cv.addWeighted(processingSrc, 1, invertedContourMat, 0.5, 0, combinedInvertedMat);
     //计算荧光强度
     const fluorescence=cv.mean(maskedImage,mask)[0]
     const bgIntensity=cv.mean(invertedMaskedImage,invertedMask)[0]
     // 转换为 ImageBitmap
     const combinedImageBitmap = convertMatToImageBitmap(combinedMat);
     const combinedInvertedImageBitmap = convertMatToImageBitmap(combinedInvertedMat);
     

     // 释放内存
     matsToDelete.push(
        combinedMat,
        combinedInvertedMat,
        maskedImage,
        invertedMaskedImage,
        mask,
        invertedMask,
        contourMat,
        invertedContourMat,
        processingSrc,
        gray
     );
     // 释放所有 OpenCV 对象
     matsToDelete.forEach(mat => !mat.isDeleted() && mat.delete());
     //返回结果
     return {resultsList,invertedResultsList,fluorescence,bgIntensity,combinedImageBitmap,combinedInvertedImageBitmap}
}     
//图片类型转换
const convertMatToImageBitmap = (mat) => {
    // 将BGR转换为RGBA
    const rgbaMat = new cv.Mat();
    cv.cvtColor(mat, rgbaMat, cv.COLOR_BGR2RGBA);
    // 创建ImageData
    const imageData = new ImageData(
        new Uint8ClampedArray(rgbaMat.data),
        rgbaMat.cols,
        rgbaMat.rows
    );
    // 绘制到OffscreenCanvas
    const canvas = new OffscreenCanvas(rgbaMat.cols, rgbaMat.rows);
    const ctx = canvas.getContext('2d');
    ctx.putImageData(imageData, 0, 0);
    // 转换为ImageBitmap并释放资源
    const imageBitmap = canvas.transferToImageBitmap();
    rgbaMat.delete();
    return imageBitmap;
};
// 接收主线程消息
// 线程通信
self.onmessage = (e) => {
    try {
        const result = processImage(e.data.imgObj, e.data.threshold);
        self.postMessage(result);
    } catch (error) {
        self.postMessage({
            error: error.message,
            stack: error.stack
          });
    }
};

